﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using SistemaCenterQuimPost.Entidad;  //Usado para instanciar objetos de clase Producto y agilizar el filtrado de descripción.
using SistemaCenterQuimPost.Control; //Usado para validar textBox
using SistemaCenterQuimPost.Plantillas; //necesario para obtener fecha, nombre usuario etc,

using System.IO;    //3 referencias que son necesarias para el proceso de archivos.
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;


namespace SistemaCenterQuimPost.UI
{
    public partial class frmRecibirProductos : SistemaCenterQuimPost.UI.frmGestionProductos
    {
        //----------------ATRIBUTOS--------------------------

                                             //Atributos usados para obtener datos de la base de datos.   
        private DsProveedoresPost dsProveedoresPost;
        private DsProveedoresPostTableAdapters.ProveedoresTableAdapter proveedoresTa;
       
        private DataSet2TableAdapters.RemitosTableAdapter remitosTa;
        private DataSet2TableAdapters.ProductosxRemitoTableAdapter productosxRemitoTa;
       

        private DataSet2TableAdapters.MovimientosxProductoTableAdapter movimientosDa;


        //objeto para serializar los RegistroUsuario y RegistroListaPrecio en formato binario
        private BinaryFormatter aplicadorFormato = new BinaryFormatter(); //Clase que permite serializar objeto, es decir pasarlo a binario.
        private FileStream remitoEntrada; //clase que maneja la información sobre el archvi y la forma de abrirlo.
        
        
        //----------------CONSTRUCTORES----------------------
        
        public frmRecibirProductos(int ancho, int alto)  //constructor que llaman tantos cajeros como supervisores.
        {
            InitializeComponent();

            dsProveedoresPost = new DsProveedoresPost();
            proveedoresTa = new DsProveedoresPostTableAdapters.ProveedoresTableAdapter();//inicializamos adaptadores necesarios para est interface.
            
            remitosTa = new DataSet2TableAdapters.RemitosTableAdapter();
            productosxRemitoTa = new DataSet2TableAdapters.ProductosxRemitoTableAdapter();
            movimientosDa = new DataSet2TableAdapters.MovimientosxProductoTableAdapter();

            removerControles();  //se remueve los controles heredados que no necesitamos en esta interface, por diseño no se puede

            posicionarListBox(); //se posiciona los listBox, porque por herencia en el diseño no se puede.

            this.Width = ancho;   //se establecen los tamaños d
            this.Height = alto;
            this.MinimumSize = new System.Drawing.Size(ancho, alto); //Se establece el tamaño máximo y mínimo en pixeles.
            this.MaximumSize = new System.Drawing.Size(ancho, alto);

        }

        public frmRecibirProductos()
        {
            
        }

        //----------------ESTADOS----------------------------

        private void frmRecibirProductos_Load(object sender, EventArgs e)
        {
            CheckForIllegalCrossThreadCalls = false;  //necesario para trabajar con hilos.

            this.limpiarDatos(); //deja la preparada para nuevos datos.

            obtenerProveedores(); //carga en el cboProveedores, los proveedores disponibles en base de dato

            obtenerRemitos(); //carga en el cboRemitos los archivos de remitos disponibles.

            estEsperandoOperacion(); //estado al comenzar el formulario.
        }

        //redefinido del padre.
        protected override void estEsperandoOperacion() //se redefine para que no cause conflicto. Acá no se usa
        {
            if (refrescarResgProductos) //si hace falta actualizar el refrescarResgProducto se realiza
            {
                ejecutarHiloActualizarResgProductos();

            }

            System.Windows.Forms.Control[] controlesHabilitados = {cboProveedor,dtpFecha, cboRemito, btnCargarRemito,dgvProductos , txtNumeroRemito, cboTurno, txtCodBarra, btnBusCodigo, txtDescripcion, btnBusDescripcion};
            System.Windows.Forms.Control[] controlesDeshabilitados = {lstProductosCodBarra, lstProductosDescripcion};
            System.Windows.Forms.Control[] controlesVisibles = { };
            System.Windows.Forms.Control[] controlesInvisibles = { lstProductosCodBarra, lstProductosDescripcion, lblError };

            habilitarControles(controlesHabilitados);
            deshabilitarControles(controlesDeshabilitados);
            visibleControles(controlesVisibles);
            invisibleControles(controlesInvisibles);

            errorProvider1.Clear();  //se borran los errores, si habian.

            txtCodBarra.Focus();   //se deja el foco en txtCodBarra

            estadoDelFormulario = "estEsperandoOperacion";

        }

        private void estRemitoCargadoPorArchivo()
        {
            System.Windows.Forms.Control[] controlesHabilitados = {};
            System.Windows.Forms.Control[] controlesDeshabilitados = { dgvProductos , dtpFecha, cboRemito, btnCargarRemito, txtNumeroRemito, txtCodBarra, btnBusCodigo, txtDescripcion, btnBusDescripcion, lstProductosCodBarra, lstProductosDescripcion };
            System.Windows.Forms.Control[] controlesVisibles = { };
            System.Windows.Forms.Control[] controlesInvisibles = { lstProductosCodBarra, lstProductosDescripcion, lblError };

            habilitarControles(controlesHabilitados);
            deshabilitarControles(controlesDeshabilitados);
            visibleControles(controlesVisibles);
            invisibleControles(controlesInvisibles);

            errorProvider1.Clear();  //se borran los errores, si habian

            cboProveedor.Focus();   //se deja el foco en txtCodBarra

            estadoDelFormulario = "estRemitoCargadoPorArchivo";
        }


        //----------------METODOS VARIOS---------------------

        private void obtenerProveedores() //carga en el cboProveedores los proveedores en base de datos
        {
            try
            {
                this.cboProveedor.Items.Clear(); //todo lo que tenía antes. 

                proveedoresTa.FillByVigente(dsProveedoresPost.Proveedores);

                foreach (DataRow unaFila in dsProveedoresPost.Proveedores) //Se recorre todas las filas  del centerQuimDs.Proveedores y se cargan al cboProveedores
                {
                    this.cboProveedor.Items.Add(Convert.ToString(unaFila[1]));
                }

                

            }

            catch (IndexOutOfRangeException)
            {
                //Si se produce esta excepción no se tiene en cuenta ya que podría no tener proveedores.
            }

            catch (Exception ex)
            {

                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                //Si llega a ocurrir algún error grave se cierra el formulario 
                this.Close();
            }
        }

        private void obtenerRemitos()  //carga en el cboRemitos los remitos disponibles.
        {
            this.cboRemito.Items.Clear(); //todo lo que tenía antes. 

            string directorioRemito = "C:\\Dropbox\\Datos del Sistema\\Remitos"; //seteamos el directorio desde donde leeremos los archivos

            foreach (string archivo in Directory.GetFiles(directorioRemito))  //por cada archvio en este directorio
            {
                FileInfo archivoInfo = new FileInfo(archivo);  //obtenemos información de ese directorio

                cboRemito.Items.Add(archivoInfo.Name); //mostramos solo su nombre corto.

            }

        }
        
        private void removerControles()   //Eliminar los controles que heredé pero que no los voy a usar.
        {
            this.Controls.Remove(this.lblPrecioCosto);
            this.Controls.Remove(this.txtPrecioCosto);
            this.Controls.Remove(this.lblPrecioVenta);
            this.Controls.Remove(this.txtPrecioVenta);
            this.Controls.Remove(this.lblStockActual);
            this.Controls.Remove(this.txtStockActual);
            this.Controls.Remove(this.lblCantMinima);
            this.Controls.Remove(this.txtCantMinima);
            this.Controls.Remove(this.btnAgregar);
            this.Controls.Remove(this.btnEditar);
            this.Controls.Remove(this.lblEditar);
            this.Controls.Remove(this.lblAgregar);


            this.Controls.Remove(this.lblErrorPCosto);
            this.Controls.Remove(this.lblErrorPVenta);
            this.Controls.Remove(this.lblErrorStockActual);
            this.Controls.Remove(this.lblErrorCantMin);
        }


        private void limpiarDatos() //Se deja todo los datos vacios, usado al inicio y cada nuevo remito en la interface.
        {
            cboProveedor.Text = "";
            txtNumeroRemito.Text = "";
            dtpFecha.Text = "";
            txtCodBarra.Text = "";
            txtDescripcion.Text = "";
            dgvProductos.Rows.Clear();

        }

        private void posicionarListBox()  //usado para colocar a los lstBox en su lugar, ya que por herencia en t.Diseño no se puede.
        {
            lstProductosCodBarra.Location = new Point(160, 154);
            lstProductosDescripcion.Location = new Point(569,154);
        }

        //Redefinido del padre
        protected override void actualizarResgProductos() //Se refresca el arrayList resgProductos
        {
            try
            {
                //(ALE) HACER EL FILL O COMO LO LLAMES ACA ABAJO
                //ProductosTa.FillByProductos1(centerQuimDs,...);
                productosTa.FillByNoGranel(centerQuimDs.Productos);

                resgProductos.Clear(); //Se vacia resgProductos (ArrayList)

                foreach (DataRow unaFila in centerQuimDs.Productos) //Se recorre todas las filas  del centerQuimDs.Productos y se cargan los productos al ArrayList
                {

                    resgProductos.Add(new Producto(Convert.ToString(unaFila[0]), Convert.ToString(unaFila[1])));

                }

                refrescarResgProductos = false;

            }
            catch (IndexOutOfRangeException)
            {
                //si llega a ocurrir esta excepcion no se tiene en cuenta. Podría no haber productos cargados y lanzaría esta excepción.

            }
            catch (Exception ex)
            {
                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                //Si llega a ocurrir algún error grave se cierra el formulario 
                this.Close();
            }

        }

        //se redefine desde el padre
        protected override void cargarProductoPorCodigo(string unCodBarra) //busca producto con codigo de barra único (una coincidencia) encontrado en el oHiloFiltrarCodBarra y lo carga en el dgvProductos
        {
            try
            {
                //(ALE)HACER EL FILL O COMO LO LLAMES ACA ABAJO
                //ProductosTa.FillByProductos1(centerQuimDs,unCodBarra);
                productosTa.FillByCodigo(centerQuimDs.Productos, unCodBarra);

                dgvProductos.Rows.Add(centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, 0);

                txtCodBarra.Text = ""; //se borra el txtCodBarra y Descripción
                txtDescripcion.Text = ""; 


            }
            catch (IndexOutOfRangeException)
            {

            }
            catch (Exception ex)
            {
                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                //Si llega a ocurrir algún error grave se cierra el formulario 
                this.Close();
            }
        }

        protected override void cargarProductoPorDescripcion(string unaDescripcion)  //busca el producto por descripción en la base de datos y lo carga en el dgvProductos.
        {
            //(ALE) HACER EL FILL O COMO LO LLAMES ACA ABAJO
            productosTa.FillByNombre(centerQuimDs.Productos, unaDescripcion);

            //ARREGLAR ESTO. Se carga en el dgvProductos la consulta encontrada. 

            dgvProductos.Rows.Add(centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, 0);

            txtCodBarra.Text = ""; //se borra el txtCodBarra y Descripción
            txtDescripcion.Text = ""; 


        }

        protected override void resguardarProductoActual() //esta operación aunque se hereda, se deja vacia.
        {

        }

        private void btnCargarRemito_Click(object sender, EventArgs e)
        {          
            cargarArchivoRemito(); //carga el archivo de remito al formulario.
        }

        private void cargarArchivoRemito() //carga el archivo de remito al formulario.
        {
            if (cboRemito.Text != "")
            {
                limpiarDatos(); //Se deja preparado para cargar el archivo.
                
                string nombreArchivo; //nombre del archivo para leer los datos

                nombreArchivo = "C:\\Dropbox\\Datos del Sistema\\Remitos\\" + cboRemito.Text;

                //guardar el archivo a través del objeto FileStream.
                try
                {
                    remitoEntrada = new FileStream(nombreArchivo, FileMode.Open, FileAccess.Read); //crea el objeto FileStream para obtener acceso de lectura al archivo.

                    LeerDatos();


                    //cuando ya no tiene más datos se lanza la excepcion SerializationException para informar que terminó.

                }

                catch (SerializationException)
                {
                    MessageBox.Show("Archivo leido con exito!!", "ACTUALIZACION DE PROVEEDORES", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    estRemitoCargadoPorArchivo();
                }

                catch (FormatException)
                {
                    //notifica al usuario si el archivo no existe
                    MessageBox.Show("Formato inválido", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                catch (IOException)
                {
                    //notifica al usuario si el archivo no existe
                    MessageBox.Show("El archivo especificado no existe", "RECIBIR PRODUCTOS", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }

                catch (Exception ex)
                {
                    //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                    MessageBox.Show("La conexión a la base de datos no fué exitosa. /n /n Comuniquese con su desarrollador para solucionar el problema /n /n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    this.Close();
                }

                finally
                {
                    cerrarArchivo();
                }
            }else
            {
                MessageBox.Show("No se ha seleccionado ningún archivo de remito.", "AVISO", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            
            
        }

        private void LeerDatos()
        {
            //------------LEER ENCABEZADO--------------------------
                        
            //instanciamos unRegistroListaPrecio(Serializado) para ir capturando los objetos del archivo.
            RegistroRemito unRegistroRemito = (RegistroRemito)aplicadorFormato.Deserialize(remitoEntrada);

            dtpFecha.Text = unRegistroRemito.Fecha;
            txtNumeroRemito.Text = unRegistroRemito.CodRemito.ToString();

            //------------LEER CUERPO----------------------
            do
            {           //instanciamos unRegistroListaPrecio(Serializado) para ir capturando los objetos del archivo.
                RegistroProductoRemito unRegistroProductoRemito = (RegistroProductoRemito)aplicadorFormato.Deserialize(remitoEntrada);

                if ((unRegistroProductoRemito.Descripcion.Substring(0,1) == "T") | (unRegistroProductoRemito.Descripcion.Substring(0,1) == "D"))
                {
                    dgvProductos.Rows.Add(unRegistroProductoRemito.CodProducto, unRegistroProductoRemito.Descripcion, Convert.ToInt32(unRegistroProductoRemito.Cantidad));
                }else
                {
                    dgvProductos.Rows.Add(unRegistroProductoRemito.CodProducto, unRegistroProductoRemito.Descripcion, unRegistroProductoRemito.Cantidad);
                }

            } while (remitoEntrada != null);


        }

        private void cerrarArchivo()
        {
            try
            {
                if (remitoEntrada != null)  //determina si existe el archivo
                {
                    remitoEntrada.Close();  //cierra el archivo

                    
                    File.Delete(remitoEntrada.Name); //eliminamos el archivo.
                }
            }
            catch (IOException)  //notifica al usuario del error al cerrar el archivo
            {
                MessageBox.Show("No se puede cerrar el archivo.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
        }




        //Redefinido del padre
        protected override void procesar() //se encapsulo en un método para usar cuando se presiona Enter con los textBox
        {
            if (formularioValido())
            {
                try
                {

                    DialogResult result = MessageBox.Show("¿Está seguro en recibir las unidades de los productos especificados en la grilla? ", "CONFIRMACION RECIPCIÓN DE UNIDADES DISUELTAS", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                    if (result == DialogResult.Yes)
                    {
                        agregarRemito();  //agrega un registro de remito a la tabla de Remito

                        agregarProductoXRemito(); //agrega un registro de productosXRemito a esa tabla

                        incrementarStockProductos(); //incrementa el stock del producto ingresado.

                        //Se muestra un mje de confirmación.
                        MessageBox.Show("Producto se ha ingresado con exito!!!", "AVISO", MessageBoxButtons.OK, MessageBoxIcon.Information);

                        limpiarDatos();

                        cboRemito.Text = ""; //se hace esto acá porque en limpiar datos no se puede.
                        

                        estEsperandoOperacion();
                    }

                }
                catch (IndexOutOfRangeException)
                {

                }
                catch (Exception ex)
                {
                    //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                    MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    //Si llega a ocurrir algún error en estado agregar 
                    this.Close();
                }

            }
            else
            {
                informarExistenciaError();
            }


        }

        //redefinido del padre
        protected override bool formularioValido()  
        {

            validarProveedor();

            validarTurno();

            validarGrilla();

            validarNumeroRemito();


            if ((errorProvider1.GetError(cboProveedor) == "") & (errorProvider1.GetError(txtNumeroRemito) == "") & (errorProvider1.GetError(dgvProductos) == "") & (errorProvider1.GetError(cboTurno) == ""))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void validarProveedor()
        {
            if (cboProveedor.Text.Trim() == "")
            {
                errorProvider1.SetError(cboProveedor, "Proveedor: el campo se encuentra vacio\n\n");
            }else
            {
                errorProvider1.SetError(cboProveedor, "");
            }
        }

        private void validarNumeroRemito()
        {
            if (txtNumeroRemito.Text.Trim() == "")
            {
                errorProvider1.SetError(txtNumeroRemito, "N° Remito: el campo se encuentra vacio\n\n");
            }
            else
            {
                
                errorProvider1.SetError(txtNumeroRemito, new ValidarDatos().validarLongitud("N° Remito:", txtNumeroRemito.Text,30));
                
                if ((errorProvider1.GetError(txtNumeroRemito) == "") & (errorProvider1.GetError(cboProveedor) == "")) //si no tiene errores de tipeo, se mira si ya no se ingreso el remito
                {
                    remitosTa.FillByNroRemitoyProveedor(centerQuimDs.Remitos,txtNumeroRemito.Text,obtenerCodProveedor());

                    if (centerQuimDs.Remitos.Rows.Count != 0)
                    {
                        errorProvider1.SetError(txtNumeroRemito, "El remito especificado ya ha sido ingresado para el proveedor. \n\n Reinicie la interfaz para solucionar este problema.");
                        
                        
                    }else
                    {
                        errorProvider1.SetError(txtNumeroRemito,"");

                    }


                }

            }
        }

        private void validarTurno()
        {
            if (cboTurno.Text.Trim() == "")
            {
                errorProvider1.SetError(cboTurno, "Turno: el campo se encuentra vacio\n\n");
            }
            else
            {
                errorProvider1.SetError(cboTurno, "");
            }
        }

        private void validarGrilla() //recorre todo el dataGride y verifica que los datos se encuentren correctos, si alguno está incorrecto los pinta de blanco
        {
            bool grillaSinError = true;  //inicializa el booleano que controla si el dgvProductos tiene al menos un error.
                        
            foreach(DataGridViewRow row in dgvProductos.Rows){

                string tipo = Convert.ToString(row.Cells[1].Value).Substring(0,1);  //obtiene si el tipo de producto en la fila, en base a la primera letra de la descripción
   
                if (tipo == "T" || (tipo =="D"))
                {
                    if ((new ValidarDatos().ValidarNaturalesPositivos("Fila:", Convert.ToString(row.Cells[2].Value).Trim())) == "") //No tiene error. El producto terminado o disuelto por cantidad.
                    {
                        row.Cells[2].Style.BackColor = Color.White;

                    }else      //con error en producto terminado o disuelto por cantidad
                    {
                        row.Cells[2].Style.BackColor = Color.LightPink;

                        grillaSinError = false;
                    }

                }else
                {
                    if ((new ValidarDatos().validarRealesPositvosSinCero("Fila:", Convert.ToString(row.Cells[2].Value).Trim())) == "") //No tiene error. El producto base.
                    {
                        row.Cells[2].Style.BackColor = Color.White;

                    }
                    else  //con error en producto base
                    {
                        row.Cells[2].Style.BackColor = Color.LightPink;

                        grillaSinError = false;
                    }
                }
                
            }

            
            if (grillaSinError) {
                errorProvider1.SetError(dgvProductos, "");
            }else
            {
                errorProvider1.SetError(dgvProductos, "Algunos de los campos cantidad en la grilla no contiene datos válidos.");
            }

            if (dgvProductos.RowCount == 0)
            {
                errorProvider1.SetError(dgvProductos, "La grilla no contiene productos.");
            }

        }

        private int obtenerCodUsuarioActual()  //Dato necesario para la apertura de una caja
        {
            frmPlantillaPadre unFrm = (frmPlantillaPadre)this.MdiParent;
            return unFrm.getCodUsuario();
        }


        private string obtenerNombreUsuarioActual()  //Dato necesario para la apertura de una caja
        {
            frmPlantillaPadre unFrm = (frmPlantillaPadre)this.MdiParent;
            return unFrm.getNombreUsuario();
        }


        private string obtenerFechaActual()  //Dato necesario para la apertura de una caja.
        {
            frmPlantillaPadre unFrm = (frmPlantillaPadre)this.MdiParent;
            return unFrm.getFechaActual();
        }

        private void agregarRemito()
        {
            remitosTa.InsertQueryRemito(txtNumeroRemito.Text, obtenerCodProveedor(), this.dtpFecha.Value, this.cboTurno.SelectedItem.ToString(), obtenerCodUsuarioActual());
            
        }

        private int obtenerCodProveedor()  //obtiene el codigo de proveedor seleccionado en el combo.
        {
            proveedoresTa.FillByRazon(dsProveedoresPost.Proveedores,cboProveedor.SelectedItem.ToString());

            return dsProveedoresPost.Proveedores[0].codProveedor;
        }

        private void agregarProductoXRemito() //agrega un registro a la tabla ProductosXremito
        {
           

            foreach (DataGridViewRow row in dgvProductos.Rows)
            {
                productosxRemitoTa.InsertQueryProductosxRemito(txtNumeroRemito.Text, row.Cells[0].Value.ToString(), row.Cells[1].Value.ToString(), Convert.ToDecimal(row.Cells[2].Value));
                movimientoProductoRecibidos(row.Cells[0].Value.ToString (), row.Cells[1].Value.ToString (), Convert.ToDecimal(row.Cells[2].Value),txtNumeroRemito.Text);

            }
            
        }

        private void incrementarStockProductos() //Actualiza la base de datos productos, incrementando su stock
        {
            
            foreach (DataGridViewRow row in dgvProductos.Rows)
            {
                productosTa.FillByNombre(centerQuimDs.Productos,row.Cells[1].Value.ToString());

                centerQuimDs.Productos[0].stockActual = centerQuimDs.Productos[0].stockActual + Convert.ToDouble(row.Cells[2].Value);
                
                productosTa.Update(centerQuimDs.Productos);
            }
            
        }

        private void movimientoProductoRecibidos (string codigo, string nombre, decimal cantidad, string ultimo)
        {
            movimientosDa.InsertQueryMovimientosxProducto(codigo, nombre, Convert.ToDateTime(dtpFecha.Value.ToString("d")), "A", "Ingreso por Remito Nº: " + ultimo, cantidad);
        }

        

    }
}
